/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package foxmob.mlts.component;

import foxmob.mlts.model.QuestionPaper;
import foxmob.mlts.model.FillInTheBlanksQuestion;
import foxmob.mlts.model.MultipleChoiceQuestion;
import foxmob.mlts.model.MultipleFillInBlankQuestion;
import foxmob.mlts.model.Question;
import foxmob.mlts.model.Section;
import foxmob.mlts.model.Subsection;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 *
 * @author Emmanouil Samatas
 */
public class ScoreManager {
    
    private static ScoreManager scoreManagerInstance;
    
    private ScoreManager() {
        
    }
    
    public static synchronized ScoreManager getInstanceObject() {
        if (scoreManagerInstance == null) {
            scoreManagerInstance = new ScoreManager();
        }   
        return scoreManagerInstance;
    }
    

    
     /*
     * Count the correct answers given by the student
     * @param questionPaper The student answer
     * @return int The total number of correct answers
     */
    public double getCorrectAnswers(QuestionPaper questionPaper){
        double correctAnswersCount = 0;
        for(Section section : questionPaper.getSections()) {
            correctAnswersCount += getCorrectAnswers(section);
        }
        return correctAnswersCount; 
    }
    
    
    /*
     * Count the correct answers given by the student
     * in a specific section
     */
    public double getCorrectAnswers(Section section){
        
        double correctAnswersCount = 0;
        
         for(Subsection subsection : section.getSubsections()){
                for(Question question : subsection.getQuestions()){
                    if (question instanceof MultipleChoiceQuestion){
                        MultipleChoiceQuestion mcq = (MultipleChoiceQuestion)question;
                        correctAnswersCount += (mcq.studentAnswer() == mcq.getCorrectAnswer())? 1* mcq.getWeight():0;
                       
                    }
                    else if(question instanceof FillInTheBlanksQuestion){
                        FillInTheBlanksQuestion fib = (FillInTheBlanksQuestion)question;
                        correctAnswersCount += (StringManager.containsIgnoreCase(Arrays.asList(fib.getCorrectAnswer()), fib.getStudentAnswer()))?1* fib.getWeight():0;
                    }
                    else if(question instanceof MultipleFillInBlankQuestion ){
                        MultipleFillInBlankQuestion mfib = (MultipleFillInBlankQuestion)question;
                        if (evaluateMultipleBlanksQuestion(mfib)){
                            mfib.setIsCorrect(true);
                            correctAnswersCount += 1 * mfib.getWeight();
                        }else{
                            if(mfib.getBlankAssesment() == null){
                            mfib.setIsCorrect(false);
                            //write to file.
                            }
                            else{
                                for(boolean marker : mfib.getBlankAssesment()){
                                    if(marker){
                                        correctAnswersCount += (double)1.0 * mfib.getWeight() / mfib.getBlankAssesment().length; 
                                    }
                                    mfib.setIsCorrect(true);
                                }
                            }
                        }
                        
                    }
                }
            }
        FileManager manager = FileManager.getInstanceObject();
        
        return correctAnswersCount;
    } 
    
    /*
     * Return the % percentage of the section score
     */
    public double getSectionScore(Section section){
        double correctAnswersCount = getCorrectAnswers(section);
        int totalAnswersCount = section.getQuestions().size();
        double score = correctAnswersCount * 100 / (double)totalAnswersCount;
        return score;
    }
    
    /*
     * Returns the % percentage of the question paper score
     */
    public double getQuestionPaperScore(QuestionPaper questionPaper){
        double correctAnswersCount = getCorrectAnswers(questionPaper);
        int totalAnswersCount = questionPaper.getAllQuestions().size();
        double score = correctAnswersCount * 100 / (double)totalAnswersCount;
        return score;
    }
  
    /*
     * Helper method to convert double to decimal String representation 
     */
    public String convertToPercentage(double score){
        NumberFormat df = DecimalFormat.getInstance();
        df.setMinimumFractionDigits(2);
        df.setMaximumFractionDigits(2);
        df.setMinimumIntegerDigits(1);
        df.setMaximumIntegerDigits(3);
       
        System.out.println(score);
        return  df.format(score);
    }
    
    /**
     * Method that evaluate if a question with multiple fill in the blanks questions is correct or not. To be correct 
     * all the blanks must contain correct values. 
     * @param question The question we want to assert that it is correct.
     * @return returns true if the question is correct.
     */
    public boolean evaluateMultipleBlanksQuestion(MultipleFillInBlankQuestion question){
        int correctAnswers = 0;
        if(question.getStudentAnswer() != null){
        for(int i = 0; i < question.getStudentAnswer().length; i++ ){
            if(StringManager.containsIgnoreCase(Arrays.asList(question.getCorrectAnswer().get(i)), question.getStudentAnswer()[i])){
             correctAnswers += 1;   
            }
        }
        return (correctAnswers == question.getCorrectAnswer().size())?true:false;
        }
        else{
            return false;
        }
    }
    
    
    /**
     * The method evaluates if the score report should be produced. If there are multiple choice questions with incorrect 
     * answers and there is no feedback by the marker then the score report is not available. 
     * @param answers the answers of the student
     * @return return true if the score is available
     */
    public boolean isTheScoreAvailable(QuestionPaper answers){
        for(Section section : answers.getSections()){
           for(Question question :section.getQuestions(Question.QuestionType.MULTIPLE_FILL_IN_THE_BLANK)){
               MultipleFillInBlankQuestion mbq = (MultipleFillInBlankQuestion)question;
               if(!evaluateMultipleBlanksQuestion(mbq) && mbq.getBlankAssesment() == null){
                   return false;
               }

           }
        }      
        
        return true;
    }
    
    

    
}
